// The libMesh Finite Element Library.
// Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


// Local Includes
#include "libmesh/libmesh_config.h"
#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
#include "libmesh/inf_fe.h"

namespace libMesh
{

// Anonymous namespace for local helper functions
namespace {

Real jacobi_30_00_eval(Real v, unsigned i)
{
  libmesh_assert (-1.-1.e-5 <= v && v < 1.);

  switch (i)
    {
    case 0:
      return 1.;

    case 1:
      return 2.5+2.5*v;

    case 2:
      return -.75+(4.5+5.25*v)*v;

    case 3:
      return (10.5+10.5*v)*v*v;

    case 4:
      return -1.375+
        (-5.5+
         (-2.25+
          (22.5+20.625*v)*v)*v)*v;

    case 5:
      return 1.78125+
        (-1.40625+
         (-19.6875+
          (-10.3125+
           (46.40625+40.21875*v)*v)*v)*v)*v;

    case 6:
      return -.609375+
        (6.09375+
         (-2.578125+
          (-58.4375+
           (-33.515625+
            (93.84375+78.203125*v)*v)*v)*v)*v)*v;

    case 7:
      return .34375+
        (2.40625+
         (28.875+
          (-156.40625+
           (-93.84375+
            (187.6875+151.9375*v)*v)*v)*v*v)*v)*v;

    case 8:
      return -1.3828125+
        (-6.5625+
         (8.53125+
          (108.0625+
           (21.328125+
            (-392.4375+
             (-241.71875+
              (372.9375+295.2421875*v)*v)*v)*v)*v)*v)*v)*v;

    case 9:
      return 1.57421875+
        (-3.19921875+
         (-38.390625+
          (21.328125+
           (351.9140625+
            (108.7734375+
             (-942.703125+
              (-590.484375+
               (738.10546875+574.08203125*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 10:
      return -.6308593750004547+
        (6.97265625+
         (-15.380859375+
          (-172.265625+
           (34.86328125+
            (1045.8984375+
             (397.4414062499999+
              (-2195.390625+
               (-1391.044921875+
                (1457.28515625+1117.251953125*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 11:
      return .484375+
        (3.8671875+
         (48.33984375+
          (-54.78515625+
           (-657.421875+
            (2914.5703125+
             (1249.1015625+
              (-4996.40625+
               (-3192.1484375+
                (2872.93359375+2176.46484375*v)*v)*v)*v)*v)*v*v)*v)*v)*v)*v;

    case 12:
      return -1.3544921875+
        (-7.34765625+
         (23.009765625+
          (252.01171875+
           (-156.1376953125+
            (-2248.3828125+
             (-291.45703125+
              (7744.4296875+
               (3591.1669921875+
                (-11172.51953125+
                 (-7182.333984375+
                  (5658.80859375+4244.1064453125*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 13:
      return 1.471313476557931+
        (-4.4512939453125+
         (-58.75708007812499+
          (101.489501953125+
           (1099.469604492188+
            (-355.2132568359375+
             (-7104.265136718749+
              (-1556.17236328125+
               (19841.19763183594+
                (9726.077270507813+
                 (-24639.39575195312+
                  (-15915.39916992187+
                   (11140.77941894531+8284.169311523438*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 14:
      return -.65960693359375+
        (7.6981201171875+
         (-31.34234619140625+
          (-348.248291015625+
           (365.6607055664063+
            (4241.664184570313+
             (-560.6797485351563+
              (-21145.63623046875+
               (-6007.283020019531+
                (49393.21594238281+
                 (25230.58868408203+
                  (-53737.87719726563+
                   (-34842.24151611328+
                    (21928.68347167969+16185.45684814453*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 15:
      return .5635986328125+
        (4.9749755859375+
         (69.649658203125+
          (-162.515869140625+
           (-1706.416625976563+
            (1121.359497070313+
             (14951.4599609375+
              (-60072.83020019531+
               (-20024.27673339844+
                (120145.6604003906+
                 (63349.53002929688+
                  (-116140.8050537109+
                   (-75532.13195800781+
                    (43161.21826171875+31651.56005859375*v)*v)*v)*v)*v)*v)*v)*v*v)*v)*v)*v)*v)*v)*v;

    case 16:
      return -1.327301025390625+
        (-8.02978515625+
         (40.323486328125+
          (461.88720703125+
           (-688.5540771484375+
            (-7318.34619140625+
             (2950.946044921875+
              (49182.43408203125+
               (4742.591857910156+
                (-164409.8510742188+
                 (-61126.73950195313+
                  (286739.9780273438+
                   (155039.6392822266+
                    (-249123.5229492188+
                     (-162422.4792480469+
                      (84959.45068359375+61949.59945678711*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 17:
      return 1.408035278320313+
        (-5.452835083007813+
         (-81.0135498046875+
          (238.8861083984375+
           (2508.304138183594+
            (-2508.304138183594+
             (-28427.44689941406+
              (6449.924926757813+
               (153185.717010498+
                (25978.86428833008+
                 (-436444.9200439453+
                  (-175711.5911865234+
                   (673561.0995483398+
                    (371697.5967407227+
                     (-530996.5667724609+
                      (-346917.7569580078+
                       (167263.9185333252+121348.3330535889*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 18:
      return -.6847000124835247+
        (8.346176147460938+
         (-49.9101333618164+
          (-593.8026123046875+
           (1151.772308349609+
            (11824.86236572266+
             (-8062.406158447265+
              (-102277.3809814453+
               (10020.4190826416+
                (456485.7582092285+
                 (103544.3305206299+
                  (-1129574.514770508+
                   (-483206.8757629394+
                    (1561129.906311035+
                     (876144.3351745604+
                      (-1125712.721557617+
                       (-736757.7363967896+
                        (329374.0468597412+237881.2560653686*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;


    default:
      libmesh_error_msg("bad index i = " << i);
    }
} // jacobi_30_00_eval()




Real jacobi_30_00_eval_deriv(Real v, unsigned i)
{
  libmesh_assert (-1.-1.e-5 <= v && v < 1.);

  switch (i)
    {
    case 0:
      return 0.;

    case 1:
      return 2.5;

    case 2:
      return 10.5*v+4.5;

    case 3:
      return (21.+31.5*v)*v;

    case 4:
      return -5.5+
        (-4.5+
         (67.5+82.5*v)*v)*v;

    case 5:
      return -1.40625+
        (-39.375+
         (-30.9375+
          (185.625+201.09375*v)*v)*v)*v;

    case 6:
      return 6.09375+
        (-5.15625+
         (-175.3125+
          (-134.0625+
           (469.21875+469.21875*v)*v)*v)*v)*v;

    case 7:
      return 2.40625+
        (57.75+
         (-625.625+
          (-469.21875+
           (1126.125+1063.5625*v)*v)*v)*v*v)*v;

    case 8:
      return -6.5625+
        (17.0625+
         (324.1875+
          (85.3125+
           (-1962.1875+
            (-1450.3125+
             (2610.5625+2361.9375*v)*v)*v)*v)*v)*v)*v;

    case 9:
      return -3.19921875+
        (-76.78125+
         (63.984375+
          (1407.65625+
           (543.8671875+
            (-5656.21875+
             (-4133.390625+
              (5904.84375+5166.73828125*v)*v)*v)*v)*v)*v)*v)*v;

    case 10:
      return 6.97265625+
        (-30.76171875+
         (-516.796875+
          (139.453125+
           (5229.4921875+
            (2384.6484375+
             (-15367.734375+
              (-11128.359375+
               (13115.56640625+11172.51953125*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 11:
      return 3.8671875+
        (96.6796875+
         (-164.35546875+
          (-2629.6875+
           (17487.421875+
            (8743.7109375+
             (-39971.25+
              (-28729.3359375+
               (28729.3359375+23941.11328125*v)*v)*v)*v)*v)*v*v)*v)*v)*v;

    case 12:
      return -7.34765625+
        (46.01953125+
         (756.03515625+
          (-624.55078125+
           (-11241.9140625+
            (-1748.7421875+
             (54211.0078125+
              (28729.3359375+
               (-100552.67578125+
                (-71823.33984375+
                 (62246.89453125+50929.27734375*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 13:
      return -4.4512939453125+
        (-117.51416015625+
         (304.468505859375+
          (4397.87841796875+
           (-1776.066284179688+
            (-42625.59082031249+
             (-10893.20654296875+
              (158729.5810546875+
               (87534.69543457031+
                (-246393.9575195312+
                 (-175069.3908691406+
                  (133689.3530273438+107694.2010498047*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 14:
      return 7.6981201171875+
        (-62.6846923828125+
         (-1044.744873046875+
          (1462.642822265625+
           (21208.32092285156+
            (-3364.078491210938+
             (-148019.4536132813+
              (-48058.26416015625+
               (444538.9434814453+
                (252305.8868408203+
                 (-591116.6491699219+
                  (-418106.8981933594+
                   (285072.8851318359+226596.3958740234*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 15:
      return 4.9749755859375+
        (139.29931640625+
         (-487.547607421875+
          (-6825.66650390625+
           (5606.797485351563+
            (89708.759765625+
             (-480582.6416015625+
              (-180218.4906005859+
               (1201456.604003906+
                (696844.8303222656+
                 (-1393689.660644531+
                  (-981917.7154541016+
                   (604257.0556640625+474773.4008789063*v)*v)*v)*v)*v)*v)*v)*v*v)*v)*v)*v)*v)*v;

    case 16:
      return -8.02978515625+
        (80.64697265625+
         (1385.66162109375+
          (-2754.21630859375+
           (-36591.73095703125+
            (17705.67626953125+
             (344277.0385742188+
              (37940.73486328125+
               (-1479688.659667969+
                (-611267.3950195313+
                 (3154139.758300781+
                  (1860475.671386719+
                   (-3238605.798339844+
                    (-2273914.709472656+
                     (1274391.760253906+991193.5913085938*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 17:
      return -5.452835083007813+
        (-162.027099609375+
         (716.6583251953125+
          (10033.21655273438+
           (-12541.52069091797+
            (-170564.6813964844+
             (45149.47448730469+
              (1225485.736083984+
               (233809.7785949707+
                (-4364449.200439453+
                 (-1932827.503051758+
                  (8082733.194580078+
                   (4832068.757629395+
                    (-7433951.934814453+
                     (-5203766.354370117+
                      (2676222.696533203+2062921.661911011*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;

    case 18:
      return 8.346176147460938+
        (-99.8202667236328+
         (-1781.407836914063+
          (4607.089233398438+
           (59124.31182861328+
            (-48374.43695068359+
             (-715941.6668701171+
              (80163.35266113281+
               (4108371.823883056+
                (1035443.305206299+
                 (-12425319.66247559+
                  (-5798482.509155273+
                   (20294688.78204345+
                    (12266020.69244385+
                     (-16885690.82336426+
                      (-11788123.78234863+
                       (5599358.796615601+4281862.609176635*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v)*v;


    default:
      libmesh_error_msg("bad index i = " << i);
    }
} // jacobi_30_00_eval_deriv()


} // anonymous namespace



  // Specialize the eval() function for 1, 2, and 3 dimensions and the CARTESIAN mapping type
  // to call the local helper function from the anonymous namespace.
template <> Real InfFE<1,JACOBI_30_00,CARTESIAN>::eval(Real v, Order, unsigned i) { return jacobi_30_00_eval(v, i); }
template <> Real InfFE<2,JACOBI_30_00,CARTESIAN>::eval(Real v, Order, unsigned i) { return jacobi_30_00_eval(v, i); }
template <> Real InfFE<3,JACOBI_30_00,CARTESIAN>::eval(Real v, Order, unsigned i) { return jacobi_30_00_eval(v, i); }

// Specialize the eval_deriv() function for 1, 2, and 3 dimensions and the CARTESIAN mapping type
// to call the local helper function from the anonymous namespace.
template <> Real InfFE<1,JACOBI_30_00,CARTESIAN>::eval_deriv(Real v, Order, unsigned i) { return jacobi_30_00_eval_deriv(v, i); }
template <> Real InfFE<2,JACOBI_30_00,CARTESIAN>::eval_deriv(Real v, Order, unsigned i) { return jacobi_30_00_eval_deriv(v, i); }
template <> Real InfFE<3,JACOBI_30_00,CARTESIAN>::eval_deriv(Real v, Order, unsigned i) { return jacobi_30_00_eval_deriv(v, i); }

} // namespace libMesh

#endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
